if !exists('*systemlist')
    echoe 'function systemlist() is required when using leovim.'
    finish
elseif !has('patch-7.4.330') && !has('nvim')
    echoe 'vim 7.4.330 is at least required when uing leovim.'
    finish
elseif !has('nvim-0.6') && has('nvim')
    echoe 'neovim 0.6 is at least required when using leovim.'
    finish
endif
" --------------------------
" set dirs
" --------------------------
let $LEOVIM_PATH = expand('~/.leovim')
let $BOOSTUP_PATH = expand($LEOVIM_PATH . '/boostup')
" set config path
let $STD_PATH = expand($BOOSTUP_PATH . '/stdpath')
let $VIM_PATH = expand($BOOSTUP_PATH . '/vimpath')
let $ADD_PATH = expand($VIM_PATH . '/addpath')
let $SET_PATH = expand($VIM_PATH . '/setpath')
let $CFG_PATH = expand($SET_PATH . '/cfg')
let $LUA_PATH = expand($SET_PATH . '/lua')
" --------------------------
" set rtp
" --------------------------
set rtp^=$LEOVIM_PATH/pack
set rtp^=$STD_PATH
" --------------------------
" set pack path
" --------------------------
if exists(':packadd')
    set packpath^=$LEOVIM_PATH
    if !exists('g:vscode')
        set packpath^=$BOOSTUP_PATH
    endif
endif
" --------------------------
" set opt path
" --------------------------
let $CLONE_OPT_PATH = expand($LEOVIM_PATH . '/pack/clone/opt')
let $FORK_OPT_PATH = expand($BOOSTUP_PATH . '/pack/fork/opt')
let $LEO_OPT_PATH = expand($BOOSTUP_PATH . '/pack/leo/opt')
" --------------------------
" gui_running && OS
" --------------------------
if has('gui_running')
    let s:gui_running = 1
    if get(g:, 'leovim_loaded', 0) == 0
        set guioptions-=e
        set guioptions-=T
        set guioptions-=r
        set guioptions-=R
        set guioptions-=l
        set guioptions-=L
        set guioptions-=m
        set guioptions-=
    endif
elseif has('nvim')
    if has('gui_vimr')
        let s:gui_running = 1
    else
        if exists('g:GuiLoaded') && g:GuiLoaded != 0
            let s:gui_running = 1
        elseif exists('*nvim_list_uis') && len(nvim_list_uis()) > 0
            let uis = nvim_list_uis()[0]
            let s:gui_running = get(uis, 'ext_termcolors', 0)? 0 : 1
        elseif exists("+termguicolors") && (&termguicolors) != 0
            let s:gui_running = 1
        else
            let s:gui_running = 0
        endif
    endif
else
    let s:gui_running = 0
endif
function! HAS_GUI()
    return s:gui_running
endfunction
" --------------------------
" system check functions
" --------------------------
function! CYGWIN()
    return has('win32unix') && !has('macunix')
endfunction
function! WINDOWS()
    return has('win32') || has('win64')
endfunction
function! LINUX()
    return has('unix') && !has('macunix') && !has('win32unix')
endfunction
function! MACOS()
    return has('macunix')
endfunction
function! UNIX()
    return LINUX() || MACOS()
endfunction
function! MACVIM()
    return has('gui_running') && MACOS()
endfunction
if MACVIM()
    set macmeta
endif
if WINDOWS()
    if s:gui_running == 0 && !has('nvim')
        echoe "Using this config in windows vim without gui is not acceptable!"
        finish
    elseif v:version < 800 && !has('nvim') || has('nvim') && !has('nvim-0.7.2')
        echoe 'vim 8.0 or neovim 0.7.2 is at least required when uing leovim in windows.'
        finish
    endif
    let $NVIM_DATA_PATH = expand("~/AppData/Local/nvim-data")
elseif exists('g:vscode') && !has('nvim-0.8')
    echoe "vscode-neovm required nvim-0.8+!"
    finish
else
    let $NVIM_DATA_PATH = expand("~/.local/share/nvim")
endif
" --------------------------
" init directories
" --------------------------
let dir_list = {
            \ 'backupdir': '~/.vim/backup',
            \ 'viewdir':   '~/.vim/views',
            \ 'directory': '~/.vim/swap',
            \ }
if has('persistent_undo')
    if has('nvim-0.7.2')
        let dir_list['undodir'] = '~/.vim/fundo'
    else
        let dir_list['undodir'] = '~/.vim/undo'
    endif
endif
for [settingname, dirname] in items(dir_list)
    let dir = expand(dirname)
    if !isdirectory(dir)
        try
            silent! call mkdir(dir, "p")
        catch
            echo "Unable to create it. Try mkdir -p " . dir
            continue
        endtry
    endif
    exec "set " . settingname . "=" . dir
endfor
if has('nvim')
    luafile $LUA_PATH/utils.lua
    set shadafile=$HOME/.vim/shada.main
endif
" ------------------------
" mapleader
" ------------------------
let g:mapleader      = ' '
let g:maplocalleader = ','
" ------------------------
" set pack related variables
" ------------------------
let g:require_group = []
let g:leovim_installed = {}
function! Require(pack)
    return count(g:require_group, a:pack) > 0
endfunction
function! AddRequire(...) abort
    if a:0 == 0
        return
    endif
    for require in a:000
        if !Require(require)
            call add(g:require_group, require)
        endif
    endfor
endfunction
function! Planned(...)
    if empty(a:000)
        return 0
    endif
    for pack in a:000
        let pack = tolower(pack)
        if !has_key(g:leovim_installed, pack)
            return 0
        endif
    endfor
    return 1
endfunction
function! Installed(...)
    if empty(a:000)
        return 0
    endif
    for pack in a:000
        let pack = tolower(pack)
        if !has_key(g:leovim_installed, pack) || get(g:leovim_installed, pack, 0) == 0
            return 0
        endif
    endfor
    return 1
endfunction
" ---------------------------------------------------------------------
" NOTE: share.vim for vscode-neovim && (neo)vim
" ---------------------------------------------------------------------
if filereadable(expand("~/.vimrc.opt"))
    source $HOME/.vimrc.opt
endif
source $STD_PATH/main.vim
if exists("g:vscode")
    source $CFG_PATH/vscode.vim
else
    let &termencoding=&enc
    " <M-Key> map to <Nop> for neovim
    let s:metacode_group = ["'", ",", ".", ";", ":", "/", "?", "{", "}", "-", "_", "=", "+"]
    for i in range(26)
        " 65 is ascii of A
        call add(s:metacode_group, nr2char(65 + i))
        " 97 is ascii of a
        call add(s:metacode_group, nr2char(97 + i))
    endfor
    for i in range(10)
        " 48 is ascii of 0
        call add(s:metacode_group, nr2char(48 + i))
    endfor
    if has('nvim') || HAS_GUI()
        function! s:map_metacode_nop(key)
            exec "map <M-".a:key."> <Nop>"
        endfunction
        for c in s:metacode_group
            call s:map_metacode_nop(c)
        endfor
    endif
    " NOTE: source core config
    source $VIM_PATH/entry.vim
    " <M-Key> map for vim
    if !has('nvim') && HAS_GUI() == 0
        function! s:set_metacode(key)
            exec "set <M-".a:key.">=\e".a:key
        endfunction
        for c in s:metacode_group
            call s:set_metacode(c)
        endfor
    endif
endif
" ------------------------
" after
" ------------------------
if WINDOWS()
    set rtp+=$STD_PATH\\after
else
    set rtp+=$STD_PATH/after
endif
let g:leovim_loaded = 1
